package com.ljx.rag.rag.util;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2025-04-07  22:42
 */
import java.util.*;

public class TextUtil {

    private static final Set<Character> SENTENCE_DELIMITERS = new HashSet<Character>() {{
        add('.');
        add('。');
        add('!');
        add('?');
        add('\n');
    }};

    public static List<String> split(String msg, int chunkSize, int chunkOverlap) {
        // 参数校验（保持不变）
        if (msg == null || msg.isEmpty()) {
            return Collections.emptyList();
        }
        if (chunkSize <= 0) {
            throw new IllegalArgumentException("Chunk size must be positive");
        }
        if (chunkOverlap < 0 || chunkOverlap >= chunkSize) {
            throw new IllegalArgumentException("Overlap must be non-negative and smaller than chunk size");
        }

        List<String> chunks = new ArrayList<>();
        int length = msg.length();
        int start = 0;

        while (start < length) {
            int end = findChunkEnd(msg, start, Math.min(start + chunkSize, length));
            String chunk = msg.substring(start, end).trim();
            if (!chunk.isEmpty()) {
                chunks.add(chunk);
            }
            start = findNextStart(msg, end, chunkOverlap);
            if (start <= end - chunkOverlap) {
                start = end;
            }
        }
        return chunks;
    }

    private static int findChunkEnd(String text, int start, int tentativeEnd) {
        if (tentativeEnd >= text.length()) {
            return text.length();
        }
        int end = tentativeEnd;
        while (end < text.length() && !SENTENCE_DELIMITERS.contains(text.charAt(end))) {
            end++;
        }
        return end < text.length() ? end + 1 : tentativeEnd;
    }

    private static int findNextStart(String text, int currentEnd, int overlap) {
        if (overlap == 0) {
            return currentEnd;
        }
        int start = Math.max(currentEnd - overlap, 0);
        while (start > 0 && !SENTENCE_DELIMITERS.contains(text.charAt(start - 1))) {
            start--;
        }
        return start;
    }

}